﻿using DzInfo.Tools;
using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.NotePrint;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.K3.FIN.App.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DzInfo.SerivesPlugin.ZhuMuNiao
{
    [Description("啄木鸟销售订单保存或者审核时反写收款单"), HotUpdate]
    public class xsAutoOperation : AbstractOperationServicePlugIn
    {
        public override void AfterExecuteOperationTransaction(AfterExecuteOperationTransaction e)
        {
            base.AfterExecuteOperationTransaction(e);
            //var obj = e.DataEntitys.FirstOrDefault();
            string opNumber = this.FormOperation.Operation;
            //DynamicObjectCollection rows = obj["POSW_Cust_Entry100001"] as DynamicObjectCollection;
            //var glRows = rows.Select(s => s["F_POSW_Text_jtv"].ToString()).ToList();
            if (opNumber.Equals("Save"))
            {
                //所有不审核的收款单
                DynamicObjectCollection xd = Getxd(this.Context);
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateXD(x);
                    }
                }
                //所有审核的收款单
                DynamicObjectCollection un = GetUnAudit(this.Context);
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateUnAudit(x);
                    }
                }
                //剩余收款金额
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateCYJE(x);
                    }
                }
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateCYJE(x);
                    }
                }
            }
            if (opNumber.Equals("Submit"))
            {
                //所有不审核的收款单
                DynamicObjectCollection xd = Getxd(this.Context);
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateXD(x);
                    }
                }
                //所有审核的收款单
                DynamicObjectCollection un = GetUnAudit(this.Context);
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateUnAudit(x);
                    }
                }
                //剩余收款金额
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateCYJE(x);
                    }
                }
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateCYJE(x);
                    }
                }
            }
            if (opNumber.Equals("UnAudit"))
            {

                //所有不审核的收款单
                DynamicObjectCollection xd = Getxd(this.Context);
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateXD(x);
                    }
                }
                //所有审核的收款单
                DynamicObjectCollection un = GetUnAudit(this.Context);
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateUnAudit(x);
                    }
                }
                DynamicObjectCollection qcsyje = GetQcsyje();
                if (qcsyje.Count > 0)
                {
                    foreach (var x in qcsyje)
                    {
                        UpdateQcsyje(x);
                    }
                }
                //剩余收款金额
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateCYJE(x);
                    }
                }
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateCYJE(x);
                    }
                }

            }
            if (opNumber.Equals("Audit"))
            {
                //所有不审核的收款单
                DynamicObjectCollection xd = Getxd(this.Context);
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateXD(x);
                    }
                }
                //所有审核的收款单
                DynamicObjectCollection un = GetUnAudit(this.Context);
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateUnAudit(x);
                    }
                }
                //剩余收款金额
                //所有不审核的收款单
                DynamicObjectCollection QCxd = GetQCxd();
                if (QCxd.Count > 0)
                {
                    foreach (var x in QCxd)
                    {
                        UpdateQCXD(x);
                    }
                }
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateCYJE(x);
                    }
                }
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateCYJE(x);
                    }
                }

            }
            if (opNumber.Equals("Delete"))
            {
                //所有不审核的收款单
                DynamicObjectCollection xd = Getxd(this.Context);
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateXD(x);
                    }
                }
                //所有审核的收款单
                DynamicObjectCollection un = GetUnAudit(this.Context);
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateUnAudit(x);
                    }
                }
                //剩余收款金额
                if (xd.Count > 0)
                {
                    foreach (var x in xd)
                    {
                        UpdateCYJE(x);
                    }
                }
                if (un.Count > 0)
                {
                    foreach (var x in un)
                    {
                        UpdateCYJE(x);
                    }
                }
            }
        }

        private void UpdateQcsyje(DynamicObject x)
        {
            string billno = x["DH"].ToString();
            string sql = string.Format(@"/*dialect*/  UPDATE T0 SET T0.F_ZMN_SYSKJE=0 FROM T_AR_RECEIVEBILL T0 WHERE T0.FBILLNO='{0}' ", billno);
            DBUtils.Execute(this.Context, sql);
        }

        private DynamicObjectCollection GetQcsyje()
        {
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
            SELECT T0.FBILLNO DH FROM T_AR_RECEIVEBILL T0
            WHERE T0.F_ZMN_SYSKJE>0 AND T0.FBILLNO IN (
            select t1.F_POSW_TEXT_JTV from T_SAL_ORDER t0
            join POSW_t_Cust_Entry100001 t1 on t1.FID=t0.FID
            WHERE T0.FDOCUMENTSTATUS<>'C' AND T1.F_POSW_TEXT_JTV<>''
            GROUP BY t1.F_POSW_TEXT_JTV) ");
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            return doc;
        }

        private void UpdateQCXD(DynamicObject x)
        {

            string billno = x["DH"].ToString();
            decimal wsh = Convert.ToDecimal(x["WSH"]);
            decimal sh = Convert.ToDecimal(x["SH"]);
            string sql = string.Format(@"/*dialect*/  UPDATE T0 SET T0.F_ZMN_XDSYJE={0},T0.F_ZMN_SYSKJE={1} FROM T_AR_RECEIVEBILL T0 WHERE T0.FBILLNO='{2}' ", wsh, sh, billno);
            DBUtils.Execute(this.Context, sql);
        }

        private DynamicObjectCollection GetQCxd()
        {
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
            SELECT T0.DH,T0.JE ZE,ISNULL(T1.JE,0) WSH,T0.JE-ISNULL(T1.JE,0) SH
            FROM (
            select t1.F_POSW_TEXT_JTV DH,SUM(T1.F_POSW_AMOUNT_0JM) JE 
            from T_SAL_ORDER t0
            join POSW_t_Cust_Entry100001 t1 on t1.FID=t0.FID
            WHERE T1.F_POSW_TEXT_JTV<>''
            GROUP BY t1.F_POSW_TEXT_JTV) T0
            LEFT JOIN (
            select t1.F_POSW_TEXT_JTV DH,SUM(T1.F_POSW_AMOUNT_0JM) JE 
            from T_SAL_ORDER t0
            join POSW_t_Cust_Entry100001 t1 on t1.FID=t0.FID
            WHERE T1.F_POSW_TEXT_JTV<>'' AND T0.FDOCUMENTSTATUS<>'C'
            GROUP BY t1.F_POSW_TEXT_JTV) T1 ON T1.DH=T0.DH  ");
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            return doc;
        }

        private DynamicObjectCollection Getqcsyskje()
        {
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
            select sum(t1.F_POSW_AMOUNT_0JM) je,t1.F_POSW_TEXT_JTV BILLNO from T_SAL_ORDER t0
            join POSW_t_Cust_Entry100001 t1 on t1.FID=t0.FID
            WHERE T0.FDOCUMENTSTATUS='C'
            GROUP BY t1.F_POSW_TEXT_JTV  ");
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            return doc;
        }

        private void UpdateCYJE(DynamicObject x)
        {
            string billno = x["BILLNO"].ToString();
            string sql = string.Format(@"/*dialect*/  UPDATE T0 SET T0.F_ZMN_SSYSKJE=T0.FREALRECAMOUNTFOR-T0.F_ZMN_XDSYJE-T0.F_ZMN_SYSKJE-T0.F_zmn_fhxdje-T0.F_zmn_fhsyje FROM T_AR_RECEIVEBILL T0 WHERE T0.FBILLNO='{0}' ", billno);
            DBUtils.Execute(this.Context, sql);
        }

        private void UpAll(DynamicObject x)
        {
            string billno = x["FBILLNO"].ToString();
            string sql = string.Format(@"/*dialect*/  UPDATE T0 SET T0.F_ZMN_XDSYJE=0,T0.F_ZMN_SYSKJE=0,T0.F_ZMN_SSYSKJE=T0.FREALRECAMOUNTFOR FROM T_AR_RECEIVEBILL T0 WHERE T0.FBILLNO='{0}' ", billno);
            DBUtils.Execute(this.Context, sql);
        }

        private DynamicObjectCollection GetAll()
        {
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
            SELECT DISTINCT T0.FBILLNO FROM T_AR_RECEIVEBILL T0  ");
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            return doc;
        }

        private void UpdateUnAudit2(DynamicObject x)
        {
            decimal je = 0m;
            string billno = x["BILLNO"].ToString();
            string sql = string.Format(@"/*dialect*/  UPDATE T0 SET T0.F_ZMN_SYSKJE={0} FROM T_AR_RECEIVEBILL T0 WHERE T0.FBILLNO='{1}' ", je, billno);
            DBUtils.Execute(this.Context, sql);
        }

        private void UpdateUnAudit(DynamicObject x)
        {
            decimal je = Convert.ToDecimal(x["je"]);
            string billno = x["BILLNO"].ToString();
            string sql = string.Format(@"/*dialect*/  UPDATE T0 SET T0.F_ZMN_SYSKJE={0} FROM T_AR_RECEIVEBILL T0 WHERE T0.FBILLNO='{1}' ", je, billno);
            DBUtils.Execute(this.Context, sql);
        }

        private DynamicObjectCollection GetUnAudit(Context context)
        {
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
            select sum(t1.F_POSW_AMOUNT_0JM-F_zmn_fhsyje-F_zmn_fhsyje2) je,t1.F_POSW_TEXT_JTV BILLNO from T_SAL_ORDER t0
            join POSW_t_Cust_Entry100001 t1 on t1.FID=t0.FID
            WHERE T0.FDOCUMENTSTATUS='C' AND t1.F_POSW_TEXT_JTV<>''
            GROUP BY t1.F_POSW_TEXT_JTV  ");
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            return doc;
        }

        private void UpdateXD(DynamicObject x)
        {
            decimal je = Convert.ToDecimal(x["je"]);
            string billno = x["BILLNO"].ToString();
            string sql = string.Format(@"/*dialect*/  UPDATE T0 SET T0.F_ZMN_XDSYJE={0} FROM T_AR_RECEIVEBILL T0 WHERE T0.FBILLNO='{1}' ", je, billno);
            DBUtils.Execute(this.Context, sql);
        }

        private DynamicObjectCollection Getxd(Context context)
        {
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
                 select sum(t1.F_POSW_AMOUNT_0JM-F_zmn_fhsyje-F_zmn_fhsyje2) je,t1.F_POSW_TEXT_JTV BILLNO from T_SAL_ORDER t0
                 join POSW_t_Cust_Entry100001 t1 on t1.FID=t0.FID
                 WHERE T0.FDOCUMENTSTATUS<>'C' AND t1.F_POSW_TEXT_JTV<>''
                 GROUP BY t1.F_POSW_TEXT_JTV ");
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            return doc;
        }

        private void UpSalYsyje(int fid, decimal ysyje)
        {
            string sql = string.Format(@"/*dialect*/  UPDATE T0 SET T0.F_ZMN_YSYSKJEHJ={0} FROM T_SAL_ORDER T0 WHERE T0.FID={1} ", ysyje, fid);
            DBUtils.Execute(this.Context, sql);
        }

        private void UpSkCYJE(string skBillno, decimal skzje, decimal sumJe, decimal shje)
        {
            decimal cyje = skzje - sumJe - shje;
            string sql = string.Format(@"/*dialect*/  update t0 set t0.F_ZMN_SSYSKJE={0} from T_AR_RECEIVEBILL t0 where t0.FBILLNO='{1}' ", cyje, skBillno);
            DBUtils.Execute(this.Context, sql);
        }

        private decimal GetSkzje(string skBillno)
        {
            string sql = string.Format(@"/*dialect*/ 
            select t0.FREALRECAMOUNTFOR from T_AR_RECEIVEBILL t0 where t0.FBILLNO='{0}' ", skBillno);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            if (doc.Count > 0)
            {
                return Convert.ToDecimal(doc[0][0]);
            }
            return 0;
        }

        private void UpSkshje(string skBillno, decimal shje)
        {
            string sql = string.Format(@"/*dialect*/  update t0 set t0.F_ZMN_SYSKJE={0} from T_AR_RECEIVEBILL t0 where t0.FBILLNO='{1}' ", shje, skBillno);
            DBUtils.Execute(this.Context, sql);
        }

        private decimal GetShje(string skBillno, string opNumber)
        {
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
                select sum(t1.F_POSW_AMOUNT_0JM) je from T_SAL_ORDER t0
                join POSW_t_Cust_Entry100001 t1 on t1.FID=t0.FID
                where t0.FDOCUMENTSTATUS='c' and t1.F_POSW_TEXT_JTV='{0}' ", skBillno);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            if (doc.Count > 0)
            {
                return Convert.ToDecimal(doc[0][0]);
            }
            return 0;
        }

        private void UpSksyje(string skBillno, decimal sumJe)
        {
            string sql = string.Format(@"/*dialect*/  update t0 set t0.F_ZMN_XDSYJE={0} from T_AR_RECEIVEBILL t0 where t0.FBILLNO='{1}' ", sumJe, skBillno);
            DBUtils.Execute(this.Context, sql);
        }

        private decimal GetSYJE(string skBillno, string opNumber)
        {
            string sql = "";
            sql = string.Format(@"/*dialect*/ 
                select sum(t1.F_POSW_AMOUNT_0JM) je from T_SAL_ORDER t0
                join POSW_t_Cust_Entry100001 t1 on t1.FID=t0.FID
                where t0.FDOCUMENTSTATUS<>'c' and t1.F_POSW_TEXT_JTV='{0}' ", skBillno);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            if (doc.Count > 0)
            {
                return Convert.ToDecimal(doc[0][0]);
            }
            return 0;
        }

        /// <summary>
        /// 检查明细行每行的含税价是否大于等于价目表含税价
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private bool GetJmb(DynamicObject obj, DynamicObject cust)
        {
            string date = Convert.ToDateTime(obj["Date"]).ToString("yyyy-MM-dd");
            int custId = cust == null ? 0 : Convert.ToInt32(cust["id"]);
            DynamicObjectCollection rows = obj["SaleOrderEntry"] as DynamicObjectCollection;
            foreach (var row in rows)
            {
                DynamicObject mat = row["MaterialId"] as DynamicObject;
                int matId = mat == null ? 0 : Convert.ToInt32(mat["id"]);
                decimal jmbPrice = GetJmbPrice(matId, custId, date);
                decimal taxPrice = Convert.ToDecimal(row["TaxPrice"]);
                if (taxPrice < jmbPrice)
                {
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 获取价目表价格
        /// </summary>
        /// <param name="matId"></param>
        /// <param name="custId"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        private decimal GetJmbPrice(int matId, int custId, string date)
        {
            decimal jm = 0;
            string sql = string.Format(@"/*dialect*/ 
            SELECT T2.FPRICE
            FROM T_SAL_PRICELIST T0
            JOIN T_SAL_APPLYCUSTOMER T1 ON T1.FID=T0.FID
            JOIN T_SAL_PRICELISTENTRY T2 ON T2.FID=T0.FID
            WHERE T2.FMATERIALID={0} AND T1.FCUSTID={1} AND T2.FEFFECTIVEDATE<='{2}' AND T2.FEXPRIYDATE>='{3}'
            AND T0.FDOCUMENTSTATUS='C' AND T0.FFORBIDSTATUS='A'
            ORDER BY T0.FEFFECTIVEDATE DESC ", matId, custId, date, date);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            if (doc.Count > 0)
            {
                jm = Convert.ToDecimal(doc[0][0]);
            }
            return jm;
        }

        /// <summary>
        /// 判断明细行规格型号是否包含OEM，如包含则按到款50%校验，同时比较含税单价与价目表单价，大于等于则自动审核
        /// </summary>
        /// <param name="obj"></param>
        private bool IsOME(DynamicObject obj, decimal xs, decimal ys, bool isJmb, EndOperationTransactionArgs e)
        {
            DynamicObjectCollection rows = obj["SaleOrderEntry"] as DynamicObjectCollection;
            List<bool> isOem = new List<bool>();
            var oem = rows.Select(s => (s["MaterialId"] as DynamicObject)["Specification"].ToString());
            foreach (var item in oem)
            {
                if (item.Contains("OEM"))
                {
                    isOem.Add(true);
                }
            }
            if (isOem.Count > 0)
            {
                if (ys >= xs / 2)
                {
                    if (isJmb)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 自动审核
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="e"></param>
        private void AutoAudit(DynamicObject obj, EndOperationTransactionArgs e)
        {
            var ids = e.DataEntitys.Select(s => s["id"]).ToArray();
            var res = AppServiceContext.SubmitService.Submit(this.Context, this.BusinessInfo, ids, "Submit", null);
            this.OperationResult.MergeResult(res);
            if (res.IsSuccess)
            {
                this.OperationResult.MergeResult(AppServiceContext.AuditService.Audit(this.Context, this.BusinessInfo, ids, OperateOption.Create()));
            }
        }

        /// <summary>
        /// 先判断明细是否有赠品行，有则不自动审核，标识为审批流
        /// </summary>
        /// <param name="obj"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void CheckRowsIsZP(DynamicObject obj)
        {
            //SaleOrderEntry
            DynamicObjectCollection rows = obj["SaleOrderEntry"] as DynamicObjectCollection;
            var zp = rows.Select(s => Convert.ToBoolean(s["IsFree"]));
            if (zp.Any(x => x))
            {
                //标识审批标识为是
                SetStatues(obj, 1);
            }
        }
        /// <summary>
        /// 关联的收款单可关联金额
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private decimal GetYS(DynamicObject obj)
        {
            decimal ys = 0;
            DynamicObjectCollection ysRow = obj["POSW_Cust_Entry100001"] as DynamicObjectCollection;
            ys = ysRow.Select(s => s["F_POSW_Amount_0jm"]).Sum(p => Convert.ToDecimal(p));
            return ys;
        }
        /// <summary>
        /// 价格合计
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        private decimal GetXS(DynamicObject obj)
        {
            decimal xs = 0;
            DynamicObjectCollection fine = obj["SaleOrderFinance"] as DynamicObjectCollection;
            xs = Convert.ToDecimal(fine[0]["BillAllAmount"]);
            return xs;
        }

        private void SetStatues(DynamicObject obj, int v)
        {
            IBillView val = KingdeeTools.CreateBillView(this.Context, this.BusinessInfo.GetForm().Id);
            val.Model.DataObject = obj;
            val.Model.SetValue("F_POSW_CheckBox_xlc", v, 0);
            List<DynamicObject> objects = new List<DynamicObject>();
            objects.Add(val.Model.DataObject);
            AppServiceContext.SaveService.Save(this.Context, objects.ToArray());
        }

        /// <summary>
        /// 加载所有列
        /// </summary>
        /// <param name="e"></param>
        public override void OnPreparePropertys(PreparePropertysEventArgs e)
        {
            base.OnPreparePropertys(e);
            FormMetadata meta = MetaDataServiceHelper.GetFormMetaData(this.Context, this.BusinessInfo.GetForm().Id);
            var fieldKeyList = meta.BusinessInfo.GetBosFields().Select(x => x.Field.Key).ToList();
            for (int i = 0; i < fieldKeyList.Count; i++)
            {
                e.FieldKeys.Add(fieldKeyList[i]);
            }
        }
    }
}
